package com.idc.common.util;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.idc.common.cache.RedisClient;
import com.idc.common.constant.RedisKey;
import com.idc.quotation.config.LoginConfig;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class JwtUtil implements RedisKey {

	@Autowired
	private LoginConfig loginConfig;

	private String SECRET_KEY;
	private long EXPIRATION_TIME;

	@PostConstruct
	public void init() {
		SECRET_KEY = loginConfig.getTokenSecretKey();
		EXPIRATION_TIME = 1000L * 60 * 60 * loginConfig.getTokenExpirationTime(); // 转为毫秒
	}

    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, username);
    }

	public String generateToken(String username, Map<String, Object> claims) {
		return createToken(claims, username);
	}

    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public boolean validateToken(String token, String username) {
        final String extractedUsername = extractUsername(token);
        return (extractedUsername.equals(username) && !isTokenExpired(token));
    }

	@Autowired
	private RedisClient redisClient;
	public boolean validateRedisToken(String token) {
		if (StringUtils.isEmpty(token)) {
			return false;
		}
		try {
			String username = extractUsername(token);
			if (StringUtils.isEmpty(username)) {
				return false;
			}
			String redisToken = redisClient.get(LOGIN_TOKEN_KEY + username);
			return token.equals(redisToken);
		} catch (Exception e) {
			LogUtil.error(log, "token analysis error: {}", token, e);
			return false;
		}
	}

    public String extractUsername(String token) {
        return extractAllClaims(token).getSubject();
    }

	public Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
    }

	public boolean isTokenExpired(String token) {
        return extractAllClaims(token).getExpiration().before(new Date());
    }
}
